/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.demo.compiler;

import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 * Group: vacoor
 * Date: 13-7-7
 * Time: 下午3:17
 * To change this template use File | Settings | File Templates.
 */
public class CompilerUtils {
    private static class JavaStringObject extends SimpleJavaFileObject {
        private String content;

        protected JavaStringObject(String name, String content) {
            super(URI.create(name + ".java"), Kind.SOURCE);
            this.content = content;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            return content;
        }
    }

    public static Class<?> compile(File javaFiles) throws ClassNotFoundException {
        // Gets System Compiler
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        // 最简单的, 输入流,输出流, 错误流, 传递给javac 的参数
//        int run = compiler.run(null, null, null, "-d", ".", "Hello.java");
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);

        Iterable<? extends JavaFileObject> javaFileObjects = fileManager.getJavaFileObjects(javaFiles);

        String outPath = ToolProvider.getSystemToolClassLoader().getResource(".").getPath();
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, Arrays.asList("-d", outPath), null, javaFileObjects);

        if (!task.call()) {
            return null;
        }
        return ToolProvider.getSystemToolClassLoader().loadClass("");
    }

    public static void compile(String name, String content) throws ClassNotFoundException, MalformedURLException, URISyntaxException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        Matcher matcher = Pattern.compile("package\\s+([a-zA-Z0-9.]+)\\s*;").matcher(content);
        if (matcher.find()) {
            System.out.println(matcher.group(1));
        }
        System.exit(0);
        //
        JavaFileObject fileObject = new JavaStringObject("Hello", content);
        String path = ToolProvider.getSystemToolClassLoader().getResource(".").toURI().getPath();
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, Arrays.asList("-d", path), null, Arrays.asList(fileObject));
        Boolean call = task.call();
        System.out.println(call);
        Class<?> clazz = ToolProvider.getSystemToolClassLoader().loadClass("org.vacoor.test.Hello");
//        Class<?> clazz = new URLClassLoader(new URL[]{new URL("file://")}).loadClass("org.vacoor.test.Hello");
        Method m = clazz.getDeclaredMethod("main", String[].class);
        System.out.println(m);
        m.invoke(clazz.newInstance(), new String[]{null});
    }

    public static void testString() throws ClassNotFoundException, MalformedURLException, URISyntaxException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        StringWriter source = new StringWriter();
        PrintWriter writer = new PrintWriter(source);
        writer.println("package org.vacoor.test;");
        writer.println("public class Hello {");
        writer.println("public static void main(String[] args) {");
        writer.println("System.out.println(\"hello\");");
        writer.println("}");
        writer.println("}");
        writer.flush();
        writer.close();
//        compile(source.toString());
    }

    public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, URISyntaxException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//        compile(new String[0]);
//        testString();
//        compile(new File[0]);
    }
}
